package com.waylau.spring.boot.blog.service;

import java.util.ArrayList;
import java.util.List;
import java.util.Set;

import com.waylau.spring.boot.blog.domain.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;
import com.waylau.spring.boot.blog.repository.StudentRepository;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.criteria.*;
import javax.transaction.Transactional;

@Service
public class StudentServiceImpl implements StudentService{

	
	//注入StudentRepositoryJPA
	@Autowired
	StudentRepository studentReposutory;
	@PersistenceContext
	 EntityManager entityManager;

	@Override
	@Transactional
	public Student saveStudent(Student student) {
		if(null!=student.getTeacherIds()){
			for(Long i:student.getTeacherIds()){
				Teacher	teacherone = entityManager.find(Teacher.class, i);
				student.getTeachers().add(teacherone);
				teacherone.getStudents().add(student);
				entityManager.persist(student);
				entityManager.persist(teacherone);
			}
		}else {
			entityManager.persist(student);
		}
		return student;
	}

	@Override
	@Transactional
	public void removeStudent(Long id) {
		Student student=entityManager.find(Student.class,id);
		entityManager.remove(student);
	}

	@Override
	@Transactional
	public Student updateStudent(Student student) {
		Student std = entityManager.merge(student);
		if(null != student.getTeacherIds()) {
			for(long id : student.getTeacherIds()) {
				std.getTeachers().add(entityManager.getReference(Teacher.class, id));
			}
		} else {
			entityManager.merge(student);
		}
		return student;
	}

	@Override
	public Student getStudentById(Long id) {
		Student stu = studentReposutory.findOne(new Specification<Student>() {
			@Override
			public Predicate toPredicate(Root<Student> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
				Predicate id1 = cb.equal(root.get(Student_.id.getName()), id);
				query.where(id1);
				return  query.getRestriction();
			}
		});
		return stu;
	}

	@Override
	public Room getRoomById(Long id) {
		CriteriaBuilder cb = entityManager.getCriteriaBuilder();
		CriteriaQuery<Room> query = cb.createQuery(Room.class);
		Root<Room> root = query.from(Room.class);
		Predicate condition=null;
		if(null !=id){
			condition = cb.equal(root.get(Room_.id), id);
		}
		return entityManager.createQuery(query.where(condition)).getSingleResult();
	}

	@Override
	public Teacher getTeacherById(Long id) {
		Teacher teacher = entityManager.find(Teacher.class, id);
		return teacher;
	}

	@Override
	public List<Student> listStudents() {
		return studentReposutory.findAll();
	}

	@Override
	public List<Teacher> listTeachers() {
		String sql="select t from Teacher as t where 1=1";
		return entityManager.createQuery(sql).getResultList();
	}

	@Override
	public List<Student> listStudentsByNameAndAgeAndSex(String name, String sex,Integer age1,Integer age2) {
		List<Student> name1 = studentReposutory.findAll((root, query, cb) -> {
			List<Predicate> list=new ArrayList<>();
			if(null!=name){
				list.add(cb.equal(root.get(Student_.name.getName()), name));
			}
			if(null!=sex){
				list.add(cb.equal(root.get(Student_.sex.getName()), sex)) ;
			}
			if(age1!=null && age2!=null) {
				list.add(cb.between(root.get(Student_.age.getName()), age1,age2));
			}
			root.fetch("course");
			Join<Student,Course> join = root.join("course",JoinType.LEFT);
			list.add(cb.equal(join.get(Course_.name),"语文"));
			return cb.and(list.toArray(new Predicate[list.size()]));
		});
		return name1;
	}
	

}
